﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Office.Interop;

namespace MedianProblem
{
    public partial class Form1 : Form
    {
        private int pValue = 0;
        private DataTable dtData = new DataTable();
        private int columnCount = 0, rowCount = 0;
        private object[,] dataArray = new object[12, 12];
        private object[,] rawDataArray = new object[12, 12];

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void ReadData()
        {
            ofdExcelDialog.FileName = "*.xlsx";
            if (ofdExcelDialog.ShowDialog() == DialogResult.OK)
            {
                object misValue = System.Reflection.Missing.Value;

                Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
                Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(ofdExcelDialog.FileName);
                Microsoft.Office.Interop.Excel.Worksheet xlWorksheet1 = xlWorkbook.Sheets[1];
                Microsoft.Office.Interop.Excel.Range xlRange1 = xlWorksheet1.UsedRange;
                DataTable excelDataTable = new DataTable();

                for (int j = 1; j <= xlRange1.Columns.Count; j++) // Header Names
                {
                    excelDataTable.Columns.Add(xlRange1.Cells[1, j].Value2.ToString());
                }

                DataRow dataRow = null;

                for (int row = 2; row < xlRange1.Rows.Count + 1; row++)
                {
                    dataRow = excelDataTable.NewRow();
                    for (int col = 1; col <= xlRange1.Columns.Count; col++)
                    {
                        dataRow[col - 1] = (xlRange1.Cells[row, col] as Microsoft.Office.Interop.Excel.Range).Value2;
                    }
                    excelDataTable.Rows.Add(dataRow);
                }

                columnCount = xlRange1.Columns.Count;
                rowCount = xlRange1.Rows.Count;
                dataArray = xlRange1.Cells.Value2;
                rawDataArray = xlRange1.Cells.Value2;

                xlWorkbook.Close(true, misValue, misValue);
                xlApp.Quit();
                GC.SuppressFinalize(xlApp);
                dtData = excelDataTable;
                dataGridView1.DataSource = excelDataTable;
            }
        }

        private void btnUpload_Click(object sender, EventArgs e)
        {
            ReadData();
        }

        private void btnCalculate_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(txtPValue.Text))
            {
                MessageBox.Show("Lütfen p değeri giriniz.");
                return;
            }
            else
            {
                if (Int32.TryParse(txtPValue.Text, out pValue))
                {
                    object[,] tempDataArray = dataArray;
                    string[,] sumArray = new string[2, 12];
                    string[] smallestColumnArray = new string[pValue];
                    string[] smallestFilteredArray = new string[13];
                    for (int m = 1; m <= 12; m++)
                    {
                        sumArray[0, m - 1] = tempDataArray[1, m].ToString();
                    }

                    for (int i = 1; i <= pValue; i++)
                    {
                        //summation process for all column
                        for (int k = 1; k <= 12; k++)//colums
                        {
                            int ithColSum = 0;
                            for (int j = 2; j <= 13; j++)//rows
                            {
                                ithColSum += Convert.ToInt32(tempDataArray[j, k]);
                            }
                            sumArray[1, k - 1] = ithColSum.ToString();
                        }

                        //select the smallest one
                        int smallestIndex = FindTheSmallestOneIndex(sumArray);
                        smallestColumnArray[i - 1] = smallestIndex.ToString();

                        //zeroing for the smallest one
                        for (int n = 1; n <= 12; n++)
                        {
                            tempDataArray[smallestIndex + 2, n] = 0;
                        }
                    }

                    //creating table with smallest columns and all rows
                    object[,] filteredDataArray;
                    CreatingFilteredArray(rawDataArray, smallestColumnArray, out filteredDataArray);

                    //finding smallest value through selected columns
                    for (int i = 0; i < 13; i++)
                    {
                        int smallestIndex = FindTheSmallestOneIndexInRow(filteredDataArray,i);
                        smallestFilteredArray[i] = smallestIndex.ToString();
                    }
                }
            }
        }

        private int FindTheSmallestOneIndex(object[,] dataArray)
        {
            int tempSmallestValue, smallestIndex = 0;

            tempSmallestValue = Convert.ToInt32(dataArray[1, 0]);
            for (int i = 0; i < 12; i++)
            {
                int val = Convert.ToInt32(dataArray[1, i]);
                if (tempSmallestValue <= val)
                {
                    //OK
                }
                else
                {
                    tempSmallestValue = val;
                    smallestIndex = i;
                }
            }

            return smallestIndex;
        }

        private void CreatingFilteredArray(object[,] dataArray, string[] columnArray, out object[,] filteredArray)
        {
            filteredArray = new object[13, pValue];
            for (int k = 1; k <= pValue; k++)
            {
                for (int i = 2; i <= 13; i++)
                {
                    for (int j = 0; j < columnArray.Length; j++)
                    {
                        filteredArray[i - 2, k - 1] = dataArray[i, Int32.Parse(columnArray[j])+1];   
                    }
                }
            }
        }

        private int FindTheSmallestOneIndexInRow(object[,] dataArray,int ithRow)
        {
            int tempSmallestValue, smallestIndex = 0;
            tempSmallestValue = Convert.ToInt32(dataArray[ithRow, 0]);
            for (int i = 0; i < pValue; i++)
            {
                int val = Convert.ToInt32(dataArray[ithRow, i]);
                if (tempSmallestValue <= val)
                {
                    //OK
                }
                else
                {
                    tempSmallestValue = val;
                    smallestIndex = i;
                }
            }

            return smallestIndex;
        }
    }
}
